from nicegui import ui
from random import random
import flocApi as api
import traceback, json
import time
import emqx

    

def on_log():
    # print(label1.text())
    # value1 = input1.value
    # value2 = input2.value
    # print(value1,value2)
    ui.navigate.to('/main')


def login():
    #log ui
    img = ui.image('img//1.png').props("absolute-top text-center").tailwind('h-screen')
    # with ui.image("img\991138.jpg").props("center no-repeat"):
    with ui.label('').classes("absolute top-1/4 inset-x-1/3 w-1/3 rounded bg-slate-300 shadow-2xl bg-white opacity-80"):
        #使用网格布局才能使text-center生效
        with ui.grid():
            label1 = ui.label('欢迎访问！').tailwind("text-center text-2xl text-dark my-2")
            #发现一个问题，使用tailwind时无法获得控件的值,也就是说tailwind本身作为一个类仅仅起到修改控件
            #样式的作用，而且使用后就覆盖了原本的类的自身函数,可以利用.element解决此问题
            # input1 = ui.input('账号/邮箱').tailwind('text-blue-700','px-10').element
            input1 = ui.input('账号/邮箱').props("outlined").style('color: rgb(37 99 235);padding-left: 2.5rem;padding-right: 2.5rem;')
            input2 = ui.input('密码',password=True).props("outlined").style('padding-left: 2.5rem;padding-right: 2.5rem;')
            #'gap:10em'是CSS中的一种属性值，用于设置元素之间的间距。它表示间距的大小为10个字符的宽度。
            # 这个属性通常用于布局调整，可以在水平或垂直方向上增加或减少元素之间的间距。
            with ui.row().style('gap:12em'):
                link1 = ui.link('忘记密码').tailwind('ml-10 w-1/3 text-left')
                link2 = ui.link('注册账号').tailwind('ml-9 text-right')
                #单个空间用mx
            button1 = ui.button('登录',on_click=on_log).tailwind('mx-10 my-3')
    # label2 = ui.label('label ').style('color: rgb(37 99 235);padding-left: 2.5rem;padding-right: 2.5rem;')


@ui.page('/main')
def mainPage():
    with ui.card().style('border: lightgray 1px solid; width:20%; height: 100%'):
    # tight():
        ui.label('try this')


# def content():
    device_columns = [        
        {'field': 'SN', 'headerName':'SN', 'sortable': True},        
        {'field': 'type', 'headerName': '类型',  'sortable': True},
        {'field': 'name', 'headerName':'名称',  'sortable': True},        
        {'headername':'在线', 'field': 'onlineStatus',  'sortable': True, 
            # 'cellClassRules': {
            #     'green-300': 'onlineStatus == ONLINE',
            #     'red-300': 'onlineStatus != ONLINE',
            # },  
            
        },
        {'field': 'disconnectionDetails','headerName':'最近3小时',  'sortable': True},
    ]
    
    deviceLib = [
        {
            'deviceType': 'Turbidity',
            'deviceList': "['LT-739', 'LT-630', '']" 
        },
        {
            'deviceType': 'pH',
            'deviceList': "['ST-710', 'ST-1710',  '']" 
        },
        {
            'deviceType': 'Level',
            'deviceList': "['超声', '压力', '红外', '']" 
        },
    ]
    deviceModels = ['LT-739', 'LT-735','LT-630', 'LT-632', 'LT-635','ST-710','ST-1710' '']
    focus_Lengths = ['16mm','12mm', '8mm','6mm','4mm', '2.4mm']
    config_columns = [
            {'headerName': '设备名', 'field': 'deviceCategory' , 'sortable': True, 'editable': True},
            {'headerName': '设备型号', 'field': 'deviceModel', 'sortable': True, 'editable': True, 'singleClickEdit': True,
                'cellEditor': 'agSelectCellEditor',
                'cellEditorParams': {'values': deviceModels, }, 
                # ':cellEditorSelector': '''params => {                
                #     return {component: 'agSelectCellEditor', params: {values: ['Celica', 'Corolla', 'Camry']} };                
                # }
                # }''',
            },          
            {'field': 'mqtt_name','headerName' : 'MQTT消息名',  'sortable': True, 'editable': True},        
            {'field': 'unit', 'headerName' : '单位',  'sortable': True, 'editable': True},        
            {'field': 'modbus_addr', 'headerName' : 'Modbus地址',  'sortable': True, 'editable': True},        
            {'field': 'reg_addr', 'headerName' : '寄存器',  'sortable': True, 'editable': True},        
            {'field': 'etc', 'headerName' : '其它',  'sortable': True, 'editable': True},
        ]
    
    cameraModels = ['4倍变焦网络相机', '固定焦距网络相机', 'USB普通相机', 'USB高速相机 ']
    camera_columns = [
            {'headerName': '相机名', 'field': 'cameraName' , 'sortable': True, 'editable': True},
            {'headerName': '相机型号', 'field': 'cameraModel', 'sortable': True, 'editable': True, 'singleClickEdit': True,
                'cellEditor': 'agSelectCellEditor',
                'cellEditorParams': {'values': cameraModels, }, 
                # ':cellEditorSelector': '''params => {                
                #     return {component: 'agSelectCellEditor', params: {values: ['Celica', 'Corolla', 'Camry']} };                
                # }
                # }''',
            },          
            {'field': 'nickname','headerName' : '显示名称',  'sortable': True, 'editable': True},        
            {'field': 'IP_addresss','headerName' : 'IP地址',  'sortable': True, 'editable': True},        
            {'field': 'focus_length', 'headerName' : '焦距',  'sortable': True, 'editable': True, 'singleClickEdit': True,
                'cellEditor': 'agSelectCellEditor',
                'cellEditorParams': {'values': focus_Lengths, },              
             },
            {'field': 'floc', 'headerName' : '是否矾花',  'sortable': True, 'editable': True},
        ]
    
        
    device_rows = []
    config_rows = []
    camera_rows = []

    def getDeviceTypeValues(e):
        log.push(e)
        return deviceModels

    def handle_cell_value_change(e):
        # log.push(e)
        submitButton.enable()
        cancelButton.enable()
        new_row = e.args['data']
        # log.push(e.args)
        # log.push(f'第{e.args["rowId"]}行{e.args["colId"]}列被编辑为: {e.args["data"]}')
        # config_rows[:] = [row | new_row if row['id'] == new_row['id'] else row for row in config_rows]
        # config_aggrid.options['rowData'] = [row | new_row if row['id'] == new_row['id'] else row for row in config_rows]
        # config_aggrid.options['rowData'][e.args["rowId"]] = e.args["data"]
        config_aggrid.options['rowData'][int(e.args["rowId"])] = e.args["data"]
        log.push(config_aggrid.options['rowData'])


    deviceList = []
    currentSN = ''
    def getDeviceList():
        global deviceList
        success, deviceList = api.getAccessableDevice()
        # ui.notify('refresh' + str(success))
        if success:
            num = 1
            # device_rows = []
            for device in deviceList:
                try:
                    s, status = api.getDeviceStatus(device['SN'])
                    if s:
                        if status == 'OFFLINE':
                            status = '×'
                        else:
                            status = '在线'
                    else:
                        status = '未知'
                    s, disconnect = api.getOnlineRate(device['SN'], 3600 * 3)
                    if s:
                        if disconnect['time'] == 0:
                            details = ''
                        else:
                            times = disconnect['time']
                            duration = int(disconnect['duration'])
                            if duration > 60:
                                duration = f'{duration//60}分{duration%60}秒'
                            else:
                                duration = str(duration) + '秒'
                            longest = int(disconnect['longest'])
                            if longest > 60:
                                longest = f'{longest//60}分{longest%60}秒'
                            else:
                                longest = str(longest) + '秒'
                            
                            details = f'离线{times}次 共{duration} 最长{longest}'
                    else:
                        details = ''
                        log.push(disconnect)
                    device_rows.append({
                        # 'id': num,
                        'SN':device['SN'],
                        'type':device['Type'], 
                        'name':device['Name'],
                        'onlineStatus': status, 
                        'disconnectionDetails': details
                    })           
                    num += 1
                except Exception as e:
                    traceback.print_exc()        
        # device_aggrid.update()
        config_aggrid.rawdata = config_rows
        config_aggrid.update()
    
     
    async def show_config_items():
        global deviceList, currentSN
        selected = [row for row in await device_aggrid.get_selected_rows()]
        
        if len(selected) == 0:
            return
        selected = selected[0]        
        currentSN = selected['SN']
        # ui.notify(selected)
        # ui.notify(SN)
        num = 1
        config_rows = []
        
        for each in deviceList:                           
            try:                
                if each['SN'] == currentSN:                                    
                    sensorList = each['sensorList']                    
                    num = 1
                    config_aggrid.options['rowData'] = []
                    for sensor in sensorList:                        
                        sensor = json.loads(sensor)
                        config_aggrid.options['rowData'].append({
                            # 'id': num,
                            'mqtt_name': sensor['type'],
                            'deviceCategory': sensor['name'],
                            'unit': sensor['unit'],
                        })
                        num += 1                    
                    # config_rows = config_aggrid.options['rowData']
                    config_aggrid.update()
                    log.push(each)
                    camera_aggrid.options['rowData'] = []
                    cameraList = each['cameraList']
                    num = 1
                    for cam in cameraList:            
                        camera = json.loads(cam)
                        log.push(camera)            
                        # camera = json.loads(camera)
                        camera_aggrid.options['rowData'].append({
                            # 'id': num,
                            'cameraName': f'camera{num}',
                            'nickname': camera['name'],
                            'model': camera['key'],
                            'IP': camera['type'],
                            'floc': camera['floc'],
                        })
                        num += 1
                    # config_rows = config_aggrid.options['rowData']
                    camera_aggrid.update()

                    # log.push('数据')
                    # log.push(config_rows)
                    break                    
            except Exception as e:
                e = str(e)
                log.push(f'设置 config 错误 {e}')
                log.push(camera)
                return


    def submitConfig(config):        
        global currentSN
        payload = json.dumps(config_aggrid.options['rowData'])
        log.push(payload)
        emqx.publish(emqx.client, '/device/{currentSN}/configChanged', payload=payload)

    def cancelConfigChange():
        pass

    def addConfigItem():
        pass

    with ui.row():
        ui.label('可访问设备清单')
        searchInput = ui.input('SN 或 名称').props("outlined").style('color: rgb(37 99 235);padding-left: 2.5rem;padding-right: 2.5rem;')
        searchButton = ui.button('搜索')
    device_aggrid = ui.aggrid({
        'columnDefs': device_columns, 
        'rowData': device_rows, 
        'rowSelection': 'single', 
        'stopEditingWhenCellsLoseFocus': True,
        }).on('rowSelected',  show_config_items)
    
    ui.button('刷新', on_click=getDeviceList)
    # ui.button('配置信息', on_click=show_selected)
    
    ui.label('设备配置表，双击可编辑')
    config_aggrid = ui.aggrid({
                    'columnDefs': config_columns,
                    'rowData': config_rows, 
                    'rowSelection': 'single', 'stopEditingWhenCellsLoseFocus': True,
                }) \
        .on('cellValueChanged', handle_cell_value_change) \
        .style('height: 150px')
    
    with ui.row():
        submitButton = ui.button('提交', on_click=submitConfig)
        cancelButton = ui.button('复原', on_click=cancelConfigChange)
        addButton = ui.button('增加设备', on_click=addConfigItem)
        submitButton.disable()
        cancelButton.disable()
    
    camera_aggrid = ui.aggrid({
                'columnDefs': camera_columns,
                'rowData': camera_rows, 
                'rowSelection': 'single', 
                'stopEditingWhenCellsLoseFocus': True,
            })  \
            .on('cellValueChanged', handle_cell_value_change) \
            .style('height: 150px')
    
    log = ui.log()
    getDeviceList()
    
    camera_columns

login()
# mainPage()
ui.run(host='127.0.0.1', port=8081)
